package interfaces;


import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;

import valueObjects.game.Player;
import valueObjects.game.card.Card;
import valueObjects.game.card.door.CurseCard;
import valueObjects.game.card.door.MonsterCard;
import valueObjects.game.card.treasure.EquipmentCard;
import valueObjects.game.card.treasure.MiscellaneousCard;
import exception.equipment.NotEquipable;
import exception.game.GameNotSavedException;
import exception.player.CurseInvalidException;

public interface IGameManagement extends Remote, IPlayerManagement, ICardManagement, IClientServer {
	
	
	public List<IClientSender> getSessions() throws RemoteException;
	
	/**
	 * Returns the next player
	 * @param currentPlayer
	 * @return
	 */
	public IClientSender getNextPlayer(Player currentPlayer) throws RemoteException;
	
	/**
	 * Adds a miscellaneous card to others list
	 * @param p
	 * @param eCard
	 * @throws NotEquipable
	 */
	public void addMiscellaneuos(Player p, MiscellaneousCard eCard) throws NotEquipable, RemoteException;
	
	/**
	 * Changes players equipment in a specific slot
	 * @param type
	 * @param changeECard
	 * @throws NotEquipable 
	 */
	public void changeEquipment(Player p, String type, EquipmentCard changeECard) throws NotEquipable, RemoteException;
	
	/**
	 * Curses the player with the given curse card.
	 * @param c
	 * @throws CurseInvalidException
	 */
	public void curse(CurseCard c, Player p) throws CurseInvalidException, RemoteException;
	
	/**
	 * Saves the game by the given filename
	 * @param fileName
	 * @throws GameNotSavedException
	 */
	public void save(String fileName) throws GameNotSavedException, RemoteException;
	
	
	/**
	 * Returns true if the Player has something to equip on his hand cards
	 * 
	 * @param player
	 * @return true of false
	 */
	public boolean canEquip(Player player) throws RemoteException;
	
	/**
	 * calculate the end of the fight
	 * 
	 * @param currentPlayer
	 * @param currentMonster
	 * @return true or false
	 * 
	 */
	public boolean combat(Player currentPlayer, MonsterCard currentMonster) throws RemoteException;
	
	/**
	 * Returns true if the calculated end of the interaction is true.
	 * Also if the final combatlvl of the player is higher then monster's + cardsinteract
	 * @param player
	 * @param monster
	 * @param currentPlayers
	 * @return true or false
	 */
	public boolean interaction(Player player, Card monster) throws RemoteException;
	
	/**
	 * Calculates the result of the fight by the given players, who want to help.
	 * @param player
	 * @param doorCard
	 * @param currentPlayers
	 * @return
	 */
	public boolean interactionHelp(Player player, Card doorCard) throws RemoteException;
	
	/**
	 * Calculates the rewards of the Fight
	 * @param player
	 * @param monster
	 * @return 
	 */
	public void generateRewards(Player player, MonsterCard monster) throws RemoteException;
	
	/**
	 * Returns true if one of the Players in the currentPlayers is over the
	 * GameManagement.winLevel
	 * 
	 * @param player
	 * @return true of false
	 */
	public boolean playerWon() throws RemoteException;
	
	/**
	 * Checks whether the player is able to escape.
	 * 
	 * @param player
	 * @return true of false
	 */
	public boolean escapePossible(Player player) throws RemoteException;

	/**
	 * Returns the round of the game
	 * @return
	 * @throws RemoteException
	 */
	public short getRound() throws RemoteException;

	/**
	 * Sets the round of the game
	 * @param s
	 * @throws RemoteException
	 */
	public void setRound(short s) throws RemoteException;

	/**
	 * Checks whether the given player has some DebuffCards on his hands
	 * @param playerInteract
	 * @return
	 * @throws RemoteException
	 */
	public boolean canInteractAgainst(Player playerInteract) throws RemoteException;

	/**
	 * Returns true if the current Player can Handle the Combat or has a buffCard.
	 * @param player
	 * @return true of false
	 */
	public boolean canHandle(Player player) throws RemoteException;

	/**
	 * Checks whether the given player has some BuffCards on his hands to help another one
	 * @param p
	 * @return
	 */
	public boolean canInteractHelp(Player p) throws RemoteException;

	/**
	 * Sends messages from a player to others
	 * @param session the player
	 * @param message
	 * @throws RemoteException
	 */
	public void sendMessage(IClientSender session, String message) throws RemoteException;

	/**
	 * Sends a system message to all players
	 * @param string
	 * @throws RemoteException
	 */
	public void sendMessage(String string) throws RemoteException;

	/**
	 * Checks whether cards are played
	 * @return boolean
	 */
	public boolean playedCard(IClientSender session) throws RemoteException;

	public void waitForCard(IClientSender session) throws RemoteException;

}
